package mobilesmil.data;

import java.io.Serializable;
import java.util.ArrayList;

import android.graphics.Color;
import android.graphics.Paint;

public class SmilDataSet implements Serializable{

	private static final long serialVersionUID = 8395589295755308197L;
    private ArrayList<SmilResource> mResourcesByBeginTime;
    private ArrayList<SmilResource> mResourcesByEndTime;
    private Integer mCanvasWidth;
    private Integer mCanvasHeight;
    private String mBackgroundColorHexString;
    private String mFileName;
    private int mLength = 0;
    private Paint mBackgroundColor;
    private static final String DEFAULT_BACKGROUND_COLOR = "#FFFFFF";
    private static final int DEFAULT_CANVAS_HEIGHT = 455;
    private static final int DEFAULT_CANVAS_WIDTH = 320;
    
    
    public SmilDataSet() {
    	mResourcesByBeginTime = new ArrayList<SmilResource>();
    	mResourcesByEndTime = new ArrayList<SmilResource>();
    	mCanvasWidth = DEFAULT_CANVAS_WIDTH;
    	mCanvasHeight = DEFAULT_CANVAS_HEIGHT;
    	mBackgroundColorHexString = DEFAULT_BACKGROUND_COLOR;
    	mBackgroundColor = new Paint();
    	mBackgroundColor.setColor(Color.parseColor((mBackgroundColorHexString)));
    }
 
	public Integer getCanvasWidth() {
		return mCanvasWidth;
	}
	public Integer getCanvasHeight() {
		return mCanvasHeight;
	}
	public Paint getBackgroundColor() {
		return mBackgroundColor;
	}
	public String getBackgroundColorHexString() {
		return mBackgroundColorHexString;
	}
	public void setBackgroundColor(String hexColorString) {
		mBackgroundColorHexString = hexColorString;
		mBackgroundColor.setColor(Color.parseColor((hexColorString)));
	}
	
	/**
	 * This method should be called when you want to add a resource to the data set.
	 * Otherwise if backdoor methods are used, then the data set won't be configured correctly
	 * and may not play properly
	 * @param resource The resource to add
	 */
	public void addResource(SmilResource resource) {
		addResourceToBeginTimeList(resource);
		addResourceToEndTimeList(resource);
		updateLength();
	}
	
	private void addResourceToBeginTimeList(SmilResource resource) {
		boolean added = false;
		if(mResourcesByBeginTime.size() == 0) { // only item in list
			mResourcesByBeginTime.add(resource);
			added = true;
		}
		else
		{
			for(int i = 0; !added && i < mResourcesByBeginTime.size(); i++)
			{
				if(mResourcesByBeginTime.get(i).getBeginTime() > resource.getBeginTime()
					|| (mResourcesByBeginTime.get(i).getBeginTime() == resource.getBeginTime()
							&& mResourcesByBeginTime.get(i).getEndTime() > resource.getEndTime()))
				{ // if the resource at i has a larger beginTime, or the same beginTime and a larger endTime
				  // then insert the new resource before it
					mResourcesByBeginTime.add(i, resource);
					added = true;
				}
			}
			if(!added)
				mResourcesByBeginTime.add(resource);
		}
	}
	
	private void addResourceToEndTimeList(SmilResource resource) {
		boolean added = false;
		if(mResourcesByEndTime.size() == 0) { // only item in list
			mResourcesByEndTime.add(resource);
			added = true;
		}
		else
		{
			for(int i = 0; !added && i < mResourcesByEndTime.size(); i++)
			{
				if(mResourcesByEndTime.get(i).getEndTime() > resource.getEndTime())
				{ // insert before item with larger begin time
					mResourcesByEndTime.add(i, resource);
					added = true;
				}
			}
			if(!added)
				mResourcesByEndTime.add(resource);
		}
	}
	
	public void removeResource(SmilResource resource) {
		mResourcesByBeginTime.remove(resource);
		updateLength();
	}
	
	private void updateLength() {
		int maxLength = 0;
		for(SmilResource resource : mResourcesByBeginTime)
		{
			if(resource.getEndTime() > maxLength)
				maxLength = resource.getEndTime();
		}
		mLength = maxLength;
	}
	
	/**
	 * Will find if its data set contains a resource of the specified type.
	 * @param smilResourceType	should reference one of the static type fields from {@link SmilResource}
	 * @param index	the index to start searching from. The arraylist searched is referenced by {@link #getResourcesByBeginTime()}
	 * @return	the first resource with the specified type, or null if none was found.
	 */
	public SmilResource hasType(String smilResourceType, int index){
		if(index > -1)
			for(int i = index; i < mResourcesByBeginTime.size(); i ++){
				if(mResourcesByBeginTime.get(i).getType().equals(smilResourceType))
					return mResourcesByBeginTime.get(i);
			}
		
		return null;
	}
	
	public int nextIndexOfType(String smilResourceType, int index){
		if(index > -1)
			for(int i = index; i < mResourcesByBeginTime.size(); i ++){
				if(mResourcesByBeginTime.get(i).getType().equals(smilResourceType))
					return i;
			}
		
		return -1;
	}
	
	/**
	 * @return the length in seconds of how long the SMIL will play for.
	 */
	public int getLength(){
		return mLength;
	}
	public String getFileName() {
		return mFileName;
	}
	public void setFileName(String fileName) {
		this.mFileName = fileName;
	}
	public ArrayList<SmilResource> getResourcesByBeginTime() {
		return mResourcesByBeginTime;
	}
	public ArrayList<SmilResource> getResourcesByEndTime() {
		return mResourcesByEndTime;
	}
}